Skip to content

[PowerPC] Add intrinsic definition for load and store with Right Length Left-justified #148873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

lei137
Copy link
Contributor

@lei137 lei137 commented Jul 15, 2025

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Jul 15, 2025

@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-backend-powerpc

Author: Lei Huang (lei137)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/148873.diff

3 Files Affected:

  • (modified) llvm/include/llvm/IR/IntrinsicsPowerPC.td (+25)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrFuture.td (+39-22)
  • (added) llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll (+150)
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 7dd9ff7f08b8b..33c6b3011dc67 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1351,6 +1351,18 @@ def int_ppc_vsx_lxvll :
 def int_ppc_vsx_lxvp :
     DefaultAttrsIntrinsic<[llvm_v256i1_ty], [llvm_ptr_ty],
                           [IntrReadMem, IntrArgMemOnly]>;
+def int_ppc_vsx_lxvrl :
+    DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_ptr_ty, llvm_i64_ty],
+                          [IntrReadMem, IntrArgMemOnly]>;
+def int_ppc_vsx_lxvrll :
+    DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_ptr_ty, llvm_i64_ty],
+                          [IntrReadMem, IntrArgMemOnly]>;
+def int_ppc_vsx_lxvprl :
+    DefaultAttrsIntrinsic<[llvm_v256i1_ty], [llvm_ptr_ty, llvm_i64_ty],
+                          [IntrReadMem, IntrArgMemOnly]>;
+def int_ppc_vsx_lxvprll :
+    DefaultAttrsIntrinsic<[llvm_v256i1_ty], [llvm_ptr_ty, llvm_i64_ty],
+                          [IntrReadMem, IntrArgMemOnly]>;
 
 // Vector store.
 def int_ppc_vsx_stxvw4x : Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
@@ -1370,6 +1382,19 @@ def int_ppc_vsx_stxvll :
 def int_ppc_vsx_stxvp :
       Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty], [IntrWriteMem,
       IntrArgMemOnly]>;
+def int_ppc_vsx_stxvrl :
+      Intrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i64_ty],
+      [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvrll :
+      Intrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i64_ty],
+      [IntrWriteMem, IntrArgMemOnly]>;
+def int_ppc_vsx_stxvprl :
+      Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty, llvm_i64_ty], [IntrWriteMem,
+      IntrArgMemOnly]>;
+def int_ppc_vsx_stxvprll :
+      Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty, llvm_i64_ty], [IntrWriteMem,
+      IntrArgMemOnly]>;
+
 // Vector and scalar maximum.
 def int_ppc_vsx_xvmaxdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvmaxdp">;
 def int_ppc_vsx_xvmaxsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvmaxsp">;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 1ac91fadf6582..7c7627795420c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -53,36 +53,53 @@ let Predicates = [IsISAFuture] in {
 
 let Predicates = [HasVSX, IsISAFuture] in {
   let mayLoad = 1 in {
-    def LXVRL : XX1Form_memOp<31, 525, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB),
-                              "lxvrl $XT, $RA, $RB", IIC_LdStLoad, []>;
-
-    def LXVRLL : XX1Form_memOp<31, 557, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB),
-                               "lxvrll $XT, $RA, $RB", IIC_LdStLoad, []>;
-
-    def LXVPRL : XForm_XTp5_XAB5<31, 589, (outs vsrprc:$XTp),
-                                 (ins memr:$RA, g8rc:$RB),
-                                 "lxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>;
-
-    def LXVPRLL : XForm_XTp5_XAB5<31, 621, (outs vsrprc:$XTp),
-                                  (ins memr:$RA, g8rc:$RB),
-                                  "lxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>;
+    def LXVRL
+        : XX1Form_memOp<31, 525, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB),
+                        "lxvrl $XT, $RA, $RB", IIC_LdStLoad, []>;
+    def LXVRLL
+        : XX1Form_memOp<31, 557, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB),
+                        "lxvrll $XT, $RA, $RB", IIC_LdStLoad, []>;
+    def LXVPRL
+        : XForm_XTp5_XAB5<31, 589, (outs vsrprc:$XTp), (ins memr:$RA, g8rc:$RB),
+                          "lxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>;
+    def LXVPRLL
+        : XForm_XTp5_XAB5<31, 621, (outs vsrprc:$XTp), (ins memr:$RA, g8rc:$RB),
+                          "lxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>;
   }
 
   let mayStore = 1 in {
-    def STXVRL : XX1Form_memOp<31, 653, (outs),
-                               (ins vsrc:$XT, memr:$RA, g8rc:$RB),
-                               "stxvrl $XT, $RA, $RB", IIC_LdStLoad, []>;
-
-    def STXVRLL : XX1Form_memOp<31, 685, (outs),
-                                (ins vsrc:$XT, memr:$RA, g8rc:$RB),
-                                "stxvrll $XT, $RA, $RB", IIC_LdStLoad, []>;
-
+    def STXVRL
+        : XX1Form_memOp<31, 653, (outs), (ins vsrc:$XT, memr:$RA, g8rc:$RB),
+                        "stxvrl $XT, $RA, $RB", IIC_LdStLoad, []>;
+    def STXVRLL
+        : XX1Form_memOp<31, 685, (outs), (ins vsrc:$XT, memr:$RA, g8rc:$RB),
+                        "stxvrll $XT, $RA, $RB", IIC_LdStLoad, []>;
     def STXVPRL : XForm_XTp5_XAB5<31, 717, (outs),
                                   (ins vsrprc:$XTp, memr:$RA, g8rc:$RB),
                                   "stxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>;
-
     def STXVPRLL : XForm_XTp5_XAB5<31, 749, (outs),
                                    (ins vsrprc:$XTp, memr:$RA, g8rc:$RB),
                                    "stxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>;
   }
 }
+
+// Load/Store VSX Vector with Right Length Left-justified.
+// foreach Ty = [v4i32, v2i64, v128i1] in {
+foreach Ty = [v4i32, v2i64] in {
+  def : Pat<(Ty (int_ppc_vsx_lxvrl addr:$RA, i64:$RB)),
+            (LXVRL memr:$RA, g8rc:$RB)>;
+  def : Pat<(Ty (int_ppc_vsx_lxvrll addr:$RA, i64:$RB)),
+            (LXVRLL $RA, $RB)>;
+  def : Pat<(int_ppc_vsx_stxvrl Ty:$XT, addr:$RA, i64:$RB),
+            (STXVRL $XT, $RA, $RB)>;
+  def : Pat<(int_ppc_vsx_stxvrll Ty:$XT, addr:$RA, i64:$RB),
+            (STXVRLL $XT, $RA, $RB)>;
+}
+
+// Load/Store VSX Vector pair with Right Length Left-justified.
+def : Pat<(v256i1(int_ppc_vsx_lxvprl addr:$RA, i64:$RB)), (LXVPRL $RA, $RB)>;
+def : Pat<(v256i1(int_ppc_vsx_lxvprll addr:$RA, i64:$RB)), (LXVPRLL $RA, $RB)>;
+def : Pat<(int_ppc_vsx_stxvprl v256i1:$XTp, addr:$RA, i64:$RB),
+          (STXVPRL $XTp, $RA, $RB)>;
+def : Pat<(int_ppc_vsx_stxvprll v256i1:$XTp, addr:$RA, i64:$RB),
+          (STXVPRLL $XTp, $RA, $RB)>;
diff --git a/llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll b/llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll
new file mode 100644
index 0000000000000..2cbaf3c548d28
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll
@@ -0,0 +1,150 @@
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr -mcpu=future < %s | \
+; RUN:   FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN:   -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr -mcpu=future < %s | \
+; RUN:   FileCheck %s
+
+; Test for load/store to/from v4i32.
+
+define <4 x i32> @testLXVRL(ptr %a, i64 %b) {
+; CHECK-LABEL: testLXVRL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvrl v2, r3, r4
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call <4 x i32> @llvm.ppc.vsx.lxvrl(ptr %a, i64 %b)
+  ret <4 x i32> %0
+}
+declare <4 x i32> @llvm.ppc.vsx.lxvrl(ptr, i64)
+
+define <4 x i32> @testLXVRLL(ptr %a, i64 %b) {
+; CHECK-LABEL: testLXVRLL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvrll v2, r3, r4
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call <4 x i32> @llvm.ppc.vsx.lxvrll(ptr %a, i64 %b)
+  ret <4 x i32> %0
+}
+declare <4 x i32> @llvm.ppc.vsx.lxvrll(ptr, i64)
+
+define void @testSTXVRL(<4 x i32> %a, ptr %b, i64 %c) {
+; CHECK-LABEL: testSTXVRL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stxvrl v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]]
+; CHECK:         blr
+entry:
+  tail call void @llvm.ppc.vsx.stxvrl(<4 x i32> %a, ptr %b, i64 %c)
+  ret void
+}
+declare void @llvm.ppc.vsx.stxvrl(<4 x i32>, ptr, i64)
+
+define void @testSTXVRLL(<4 x i32> %a, ptr %b, i64 %c) {
+; CHECK-LABEL: testSTXVRLL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stxvrll v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]]
+; CHECK:         blr
+entry:
+  tail call void @llvm.ppc.vsx.stxvrll(<4 x i32> %a, ptr %b, i64 %c)
+  ret void
+}
+declare void @llvm.ppc.vsx.stxvrll(<4 x i32>, ptr, i64)
+
+; Test for load/store to/from v2i64.
+
+define <2 x i64> @testLXVRL2(ptr %a, i64 %b) {
+; CHECK-LABEL: testLXVRL2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvrl v2, r3, r4
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call <2 x i64> @llvm.ppc.vsx.lxvrl.v2i64(ptr %a, i64 %b)
+  ret <2 x i64> %0
+}
+declare <2 x i64> @llvm.ppc.vsx.lxvrl.v2i64(ptr, i64)
+
+define <2 x i64> @testLXVRLL2(ptr %a, i64 %b) {
+; CHECK-LABEL: testLXVRLL2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvrll v2, r3, r4
+; CHECK-NEXT:    blr
+entry:
+  %0 = tail call <2 x i64> @llvm.ppc.vsx.lxvrll.v2i64(ptr %a, i64 %b)
+  ret <2 x i64> %0
+}
+declare <2 x i64> @llvm.ppc.vsx.lxvrll.v2i64(ptr, i64)
+
+define void @testSTXVRL2(<2 x i64> %a, ptr %b, i64 %c) {
+; CHECK-LABEL: testSTXVRL2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stxvrl v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]]
+; CHECK:         blr
+entry:
+  tail call void @llvm.ppc.vsx.stxvrl.v2i64(<2 x i64> %a, ptr %b, i64 %c)
+  ret void
+}
+declare void @llvm.ppc.vsx.stxvrl.v2i64(<2 x i64>, ptr, i64)
+
+define void @testSTXVRLL2(<2 x i64> %a, ptr %b, i64 %c) {
+; CHECK-LABEL: testSTXVRLL2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    stxvrll v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]]
+; CHECK:         blr
+entry:
+  tail call void @llvm.ppc.vsx.stxvrll.v2i64(<2 x i64> %a, ptr %b, i64 %c)
+  ret void
+}
+declare void @llvm.ppc.vsx.stxvrll.v2i64(<2 x i64>, ptr, i64)
+
+; Test for load/store vectore pair.
+
+define <256 x i1> @testLXVPRL(ptr %vpp, i64 %b) {
+; CHECK-LABEL: testLXVPRL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvprl vsp34, r4, r5
+; CHECK:         blr
+entry:
+  %0 = tail call <256 x i1> @llvm.ppc.vsx.lxvprl(ptr %vpp, i64 %b)
+  ret <256 x i1> %0
+}
+declare <256 x i1> @llvm.ppc.vsx.lxvprl(ptr, i64)
+
+define <256 x i1> @testLXVPRLL(ptr %vpp, i64 %b) {
+; CHECK-LABEL: testLXVPRLL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvprll vsp34, r4, r5
+; CHECK:         blr
+entry:
+  %0 = tail call <256 x i1> @llvm.ppc.vsx.lxvprll(ptr %vpp, i64 %b)
+  ret <256 x i1> %0
+}
+declare <256 x i1> @llvm.ppc.vsx.lxvprll(ptr, i64)
+
+define void @testSTXVPRL(ptr %v, ptr %vp, i64 %len) {
+; CHECK-LABEL: testSTXVPRL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxv v2
+; CHECK-NEXT:    lxv v3
+; CHECK-NEXT:    stxvprl vsp34, r4, r5
+; CHECK-NEXT:    blr
+entry:
+  %0 = load <256 x i1>, ptr %v, align 32
+  tail call void @llvm.ppc.vsx.stxvprl(<256 x i1> %0, ptr %vp, i64 %len)
+  ret void
+}
+declare void @llvm.ppc.vsx.stxvprl(<256 x i1>, ptr, i64)
+
+define void @testSTXVPRLL(ptr %v, ptr %vp, i64 %len) {
+; CHECK-LABEL: testSTXVPRLL:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxv v2
+; CHECK-NEXT:    lxv v3
+; CHECK-NEXT:    stxvprll vsp34, r4, r5
+; CHECK-NEXT:    blr
+entry:
+  %0 = load <256 x i1>, ptr %v, align 32
+  tail call void @llvm.ppc.vsx.stxvprll(<256 x i1> %0, ptr %vp, i64 %len)
+  ret void
+}
+declare void @llvm.ppc.vsx.stxvprll(<256 x i1>, ptr, i64)

@lei137 lei137 requested a review from diggerlin July 15, 2025 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants